﻿//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	MetaWebList.cs
//  Developer:	Solomatov Igor
//  Created:	15.04.2012
// 
//  -------------------- iSharePoint -------------------- //

using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.SharePoint;

namespace Smart.Common
{
	[DebuggerDisplay("MetaWebList Name={Name} Title={Title}")]
	public class MetaWebList : MetaList
	{
		/// <summary>
		/// Content types id
		/// </summary>
		public Dictionary<string, string> ContentTypeIDs { get; set; }

		/// <summary>
		/// Content types collection
		/// </summary>
		public Dictionary<string, MetaWebContentType> ContentTypes { get; set; }

		/// <summary>
		/// List Url
		/// </summary>
		public string Url { get; set; }

		/// <summary>
		/// DispForm url
		/// </summary>
		public string DispFormUrl { get; set; }

		/// <summary>
		/// NewForm url
		/// </summary>
		public string NewFormUrl { get; set; }

		/// <summary>
		/// EditForm url
		/// </summary>
		public string EditFormUrl { get; set; }

		/// <summary>
		/// RootFolder full Url
		/// </summary>
		public string RootFolderUrl
		{
			get { return ((MetaWebScope)Scope).Url.EnsureEndsWith("/") + Url.TrimStart("/"); }
		}

		/// <summary>
		/// RootFolder server relative Url
		/// </summary>
		public string RootFolderServerRelativeUrl
		{
			get { return ((MetaWebScope)Scope).ServerRelativeUrl.EnsureEndsWith("/") + Url.TrimStart("/"); }
		}

		public MetaWebList(SPList list, MetaScope scope)
			: base(list.ID, list.GetName(), list.Title, scope)
		{
			Url = list.GetUrl();

			try
			{
				DispFormUrl = list.DefaultDisplayFormUrl;
				NewFormUrl = list.DefaultNewFormUrl;
				EditFormUrl = list.DefaultEditFormUrl;
			}
			catch (Exception x)
			{
				H.LX("MetaWebList", "MetaWebList Url: " + Url, x);
			}

			ContentTypeIDs = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			ContentTypes = new Dictionary<string, MetaWebContentType>(StringComparer.OrdinalIgnoreCase);
		}

		public override void LoadFields(object source)
		{
			var list = (SPList)source;

			foreach (SPField field in list.Fields)
			{
				try
				{
					var mf = new MetaField(field.Id, field.InternalName, field.Title, field.Type, this);

					FieldIDs[mf.Name] = mf.ID;
					FieldIDs[mf.Title] = mf.ID;
					FieldIDs[field.StaticName] = mf.ID;
					FieldIDs[mf.ID.ToString("D")] = mf.ID;
					FieldIDs[mf.ID.ToString("B")] = mf.ID;

					Fields[mf.ID] = mf;
				}
				catch (Exception x)
				{
					H.LX("MetaWebList.LoadFields", "LoadFields field.Id: " + field.Id, x);
				}
			}
		}

		/// <summary>
		/// Load content types
		/// </summary>
		public virtual void LoadContentTypes(SPList list)
		{
			if (list.ContentTypes == null)
				return;

			foreach (SPContentType ct in list.ContentTypes)
			{
				try
				{
					var mct =
						new MetaWebContentType(ct.Id.ToString(), ct.Parent.Id.ToString(), ct.Name, this)
								{
									DispFormUrl = ct.DisplayFormUrl,
									NewFormUrl = ct.NewFormUrl,
									EditFormUrl = ct.EditFormUrl
								};

					mct.LoadFields(ct);

					ContentTypeIDs[mct.Name] = mct.ID;
					ContentTypeIDs[mct.ID] = mct.ID;

					if (!ContentTypeIDs.ContainsKey(mct.ParentID))
						ContentTypeIDs[mct.ParentID] = mct.ID;

					ContentTypes[mct.ID] = mct;
				}
				catch (Exception x)
				{
					H.LX("MetaWebList.LoadContentTypes", "LoadContentTypes ct.Id: " + ct.Id, x);
				}
			}
		}

		/// <summary>
		/// Return SPField from List
		/// </summary>
		public virtual SPField Field(SPList list, string titleOrName)
		{
			var id = FieldIDs.SafeGet(titleOrName);

			var res = list.GetField(id);

			if (res == null)
				H.LT("MetaWebList:Field.Exception: field '{0}' not found at '{1}'!", titleOrName, Title);

			return res;
		}

		/// <summary>
		/// Return MetaWebContentType by content type id or name
		/// </summary>
		public virtual MetaWebContentType ContentType(string contentType)
		{
			var id = ContentTypeIDs.SafeGet(contentType);

			return
				id.IsNullOrEmpty()
					? null
					: ContentTypes.SafeGet(id);
		}

		/// <summary>
		/// Checks whether list contains child or equal content types to <paramref name="contentTypeId"/>
		/// </summary>
		public virtual bool ContainsContentType(string contentTypeId)
		{
			foreach (var contentType in ContentTypes.Values)
			{
				if (contentType.ID.IsChildContentTypeOf(contentTypeId))
					return true;
			}

			return false;
		}

		/// <summary>
		/// Return all MetaWebContentTypes by content type id
		/// </summary>
		public virtual List<MetaWebContentType> AllContentTypes(string contentTypeId)
		{
			var res = new List<MetaWebContentType>();

			foreach (var contentType in ContentTypes.Values)
			{
				if (contentType.ID.IsChildContentTypeOf(contentTypeId))
					res.Add(contentType);
			}

			return res;
		}

		/// <summary>
		/// Return DispForm url
		/// </summary>
		public virtual string GetDispFormUrl(string contentType)
		{
			var mct = contentType.IsNullOrEmpty() ? null : ContentType(contentType);

			var formurl = mct != null && !mct.DispFormUrl.IsNullOrEmpty() ? mct.DispFormUrl : DispFormUrl;

			if (formurl.IsNullOrEmpty())
				formurl = string.Concat(((MetaWebScope)Scope).Url, "/", Url, "DispForm.aspx");

			return formurl;
		}

		/// <summary>
		/// Return NewForm url
		/// </summary>
		public virtual string GetNewFormUrl(string contentType)
		{
			var mct = contentType.IsNullOrEmpty() ? null : ContentType(contentType);

			var formurl = mct != null && !mct.NewFormUrl.IsNullOrEmpty() ? mct.NewFormUrl : NewFormUrl;

			if (formurl.IsNullOrEmpty())
				formurl = string.Concat(((MetaWebScope)Scope).Url, "/", Url, "/NewForm.aspx");

			return formurl;
		}

		/// <summary>
		/// Return EditForm url
		/// </summary>
		public virtual string GetEditFormUrl(string contentType)
		{
			var mct = contentType.IsNullOrEmpty() ? null : ContentType(contentType);

			var formurl = mct != null && !mct.EditFormUrl.IsNullOrEmpty() ? mct.EditFormUrl : EditFormUrl;

			if (formurl.IsNullOrEmpty())
				formurl = string.Concat(((MetaWebScope)Scope).Url, "/", Url, "/EditForm.aspx");

			return formurl;
		}
	}
}